package com.jkgl.rsa;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Base64;

public class ASEUtils {

    // AES加密算法，使用CBC模式，PKCS5Padding填充
    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
    private static final String AES = "AES";

    // 初始化向量长度（16字节）
    private static final int IV_LENGTH = 16;

    // 预定义的静态密钥（256位/32字节）
    private static final String STATIC_KEY_BASE64 = "Kk7I3hD9LfYqRtGyVpXsWvZwA1B2C3D4";
    private static final SecretKey SECRET_KEY;

    static {
        try {
            // 从Base64字符串初始化静态密钥
            byte[] keyBytes = Base64.getDecoder().decode(STATIC_KEY_BASE64);
            SECRET_KEY = new SecretKeySpec(keyBytes, AES);
        } catch (Exception e) {
            throw new RuntimeException("Failed to initialize secret key", e);
        }
    }

    /**
     * 加密方法
     * @param plainText 明文
     * @return 加密后的Base64编码字符串（包含初始化向量）
     * @throws Exception
     */
    public static String encrypt(String plainText) throws Exception {
        // 生成随机初始化向量
        byte[] iv = new byte[IV_LENGTH];
        new SecureRandom().nextBytes(iv);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        // 初始化加密器
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, SECRET_KEY, ivParameterSpec);

        // 执行加密
        byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

        // 合并IV和加密数据
        byte[] combined = new byte[iv.length + encrypted.length];
        System.arraycopy(iv, 0, combined, 0, iv.length);
        System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);

        // 返回Base64编码的字符串
        return Base64.getEncoder().encodeToString(combined);
    }

    /**
     * 解密方法
     * @param encryptedText 加密的Base64字符串
     * @return 解密后的明文
     * @throws Exception
     */
    public static String decrypt(String encryptedText) throws Exception {
        // 解码Base64
        byte[] combined = Base64.getDecoder().decode(encryptedText);

        // 分离IV和加密数据
        byte[] iv = new byte[IV_LENGTH];
        byte[] encrypted = new byte[combined.length - IV_LENGTH];
        System.arraycopy(combined, 0, iv, 0, IV_LENGTH);
        System.arraycopy(combined, IV_LENGTH, encrypted, 0, encrypted.length);

        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        // 初始化解密器
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, SECRET_KEY, ivParameterSpec);

        // 执行解密
        byte[] decrypted = cipher.doFinal(encrypted);

        return new String(decrypted, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) {
        try {
            String originalText = "1|"+ LocalDate.now();
            System.out.println("原始文本: " + originalText);
            System.out.println("使用的静态密钥(Base64): " + STATIC_KEY_BASE64);

            // 加密
            String encryptedText = encrypt(originalText);
            URLEncoder.encode(encryptedText);
            System.out.println("加密后的数据: " + URLEncoder.encode(encryptedText));

            // 解密
            String decryptedText = decrypt(encryptedText);
            System.out.println("解密后的数据: " + decryptedText);

            // 验证加解密是否一致
            System.out.println("加解密验证: " + originalText.equals(decryptedText));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}